import axios from 'axios'
import { equalRequest } from './util'
export class RequestQueue {
  constructor (collectionTime = 50) {
    this.isSending = false
    this.collectionTime = collectionTime
    this.requestQueue = [] // 二维数组
  }

  // delete或者get时第二个参数为config
  request ({ type, url, data, config }) { // 需要合并get请求
    if (type !== 'get') { // 非get请求直接放行
      return axios[type](url, data, config)
    } else {
      if (this.isSending === false) {
        this.isSending = true
        setTimeout(() => {
          this.isSending = false
          this.send()
        }, this.collectionTime)
      }
      return new Promise((resolve, reject) => {
        this.requestQueue.push({ type, url, config, resolve, reject })
      })
    }
  }

  mergeRequestQueue (requestQueue) {
    const result = []
    requestQueue.forEach(request => {
      const { type, url, config, resolve, reject } = request
      const { _t, ...query } = config.params // 排除_t对相同判断的影响
      const requestSign = { url, query } // 使用url及query判断是否为同一个请求
      const queueSigns = result.map(requests => requests[0])
      const queueIndex = queueSigns.findIndex(queueSign => equalRequest(queueSign, requestSign))
      if (queueIndex > -1) {
        result[queueIndex].push({ resolve, reject })
      } else {
        result.push([requestSign, { type, url, config }, { resolve, reject }])
      }
    })
    return result
  }

  send () {
    const sendRequestQueue = this.mergeRequestQueue(this.requestQueue)
    this.requestQueue = []
    sendRequestQueue.map(async requestGroup => {
      const { type, url, config } = requestGroup[1]
      axios[type](url, config).then(res => {
        this.returnResult(res, 'resolve', requestGroup)
      }).catch(err => {
        this.returnResult(err, 'reject', requestGroup)
      })
    })
  }

  returnResult (res, type, requestGroup) {
    if (requestGroup.length > 3) console.log(requestGroup[0].url, '合并', requestGroup.length - 2, '次')
    for (let i = 2; i < requestGroup.length; i++) {
      if (type === 'reject') {
        // 返回错误时不进行深拷贝
        requestGroup[i][type](res)
      } else {
        // 简单的深克隆
        requestGroup[i][type](JSON.parse(JSON.stringify(res)))
      }
    }
  }
}
